﻿'         This file is Copyright © 2008-2012 Billy O'Neal and Aommaster
'                            All rights reserved.
'
' This file is released under the 2-Clause BSD license, included in LICENSE.TXT
'                           and on the MHWT website
Imports System.Environment
Imports System.Text.RegularExpressions

Friend Class BbCodeToHtmlFormatter
    Dim listTags As String = ""
    Sub StartConvert(ByVal boxText As String)
        Dim path As String = System.IO.Path.Combine(Environment.GetEnvironmentVariable("TEMP"), "preview.html")

        Dim htmlStream As New IO.FileStream(path, IO.FileMode.Create)
        Using htmlWriter As New System.IO.StreamWriter(htmlStream)
            Dim lines() As String

            lines = boxText.Split(CChar(vbCrLf))
            boxText = ""

            Dim openCodeTags As Integer = 0
            Dim val As Integer
            Dim newPosition As Integer
            Dim oldPosition As Integer
            Dim leftOfLines As String = ""
            Dim rightOfLines As String = ""
            Dim changed As Integer = 0

            For i = 0 To UBound(lines)
                newPosition = 0
                oldPosition = -1
                leftOfLines = ""
                rightOfLines = ""
                changed = 0
                'add code to convert the code tags to html tags
                lines(i) = Regex.Replace(lines(i), "\n(.*)", "$1")
                val = InStr(lines(i), "[code]")
                If val <> 0 Then
                    For j = 1 To lines(i).Length
                        newPosition = InStr(j, lines(i), "[code]")
                        If newPosition <> 0 And newPosition <> oldPosition Then
                            If openCodeTags = 0 Then
                                changed = 1
                            End If
                            openCodeTags += 1
                            oldPosition = newPosition
                        End If
                    Next
                    If (changed = 1 And openCodeTags >= 1) Then
                        leftOfLines = lines(i).Substring(0, val + 5)
                        leftOfLines = Convert(leftOfLines)
                    Else
                        leftOfLines = lines(i).Substring(0, val + 5)
                    End If


                    Try
                        rightOfLines = lines(i).Substring(val + 5, lines(i).Length - val - 5)
                    Catch ex As Exception
                        rightOfLines = ""
                    End Try


                    'at this point, lines(i) ==> leftoflines + rightoflines
                    val = InStr(rightOfLines, "[/code]")
                    If val <> 0 Then
                        newPosition = 0
                        oldPosition = -1
                        For j = 1 To rightOfLines.Length
                            newPosition = InStr(j, rightOfLines, "[/code]")
                            If newPosition <> 0 And newPosition <> oldPosition Then
                                openCodeTags -= 1
                                oldPosition = newPosition
                            End If
                        Next
                    End If
                    If openCodeTags = 0 Then
                        lines(i) = leftOfLines
                        leftOfLines = rightOfLines.Substring(0, oldPosition - 1)
                        rightOfLines = rightOfLines.Substring(oldPosition - 1, rightOfLines.Length - oldPosition + 1)
                        rightOfLines = Convert(rightOfLines)
                        lines(i) = lines(i) & leftOfLines & rightOfLines
                    Else
                        lines(i) = leftOfLines & rightOfLines
                    End If


                Else
                    newPosition = 0
                    oldPosition = -1
                    val = InStr(lines(i), "[/code]")
                    If val <> 0 Then
                        lines(i) = Regex.Replace(lines(i), "\n(.*)", "$1")
                        For j = 1 To lines(i).Length
                            newPosition = InStr(j, lines(i), "[/code]")
                            If newPosition <> 0 And newPosition <> oldPosition Then
                                openCodeTags -= 1
                                oldPosition = newPosition
                            End If
                        Next
                        If openCodeTags = 0 Then
                            leftOfLines = lines(i).Substring(0, oldPosition - 1)
                            rightOfLines = lines(i).Substring(oldPosition - 1, lines(i).Length - oldPosition + 1)
                            rightOfLines = Convert(rightOfLines)
                            lines(i) = leftOfLines & rightOfLines
                        End If



                    Else
                        If openCodeTags = 0 Then
                            lines(i) = Convert(lines(i))
                        End If
                    End If
                End If
                If openCodeTags = 0 Then
                    'insert the if statement that if all the code tags are closed, convert whatever is left
                End If

                'MsgBox(lines(i))
                boxText = boxText & lines(i) & "<br>"
            Next


            Dim finalCode As String = My.Resources.Startofhtml & boxText & My.Resources.Endofhtml
            finalCode = finalCode.Replace("<div class=codetop>CODE</div><div class=codemain><br>", "<div class=codetop>CODE</div><div class=codemain>")
            finalCode = finalCode.Replace("<div class=quotemain><br>", "<div class=quotemain>")
            finalCode = finalCode.Replace("<br><ul>", "<ul>")
            finalCode = finalCode.Replace("<br><o", "<o")
            finalCode = finalCode.Replace("<br><br><br>", "<br><br>")
            finalCode = finalCode.Replace("<ul><br><li>", "<ul><li>")
            finalCode = finalCode.Replace("</ul><br>", "</ul>")
            finalCode = finalCode.Replace("</ol><br>", "</ol>")
            finalCode = finalCode.Replace("<ol type='1'><br><li>", "<ol type='1'><li>")
            finalCode = finalCode.Replace("<ol type='a'><br><li>", "<ol type='a'><li>")
            finalCode = finalCode.Replace("<ol type='i'><br><li>", "<ol type='i'><li>")

            htmlWriter.Write(finalCode)
        End Using

    End Sub
    Private Function Convert(ByVal inputstring As String) As String
        Dim lines As String = inputstring
        Dim val As Integer

        'fix caps
        Dim theRegEx As New System.Text.RegularExpressions.Regex("\[[^\]]+]")
        For Each theMatch As System.Text.RegularExpressions.Match In theRegEx.Matches(lines)
            Dim lowerString As String = lines.Substring(theMatch.Index + 1, theMatch.Length - 2).ToLower()
            lines = lines.Remove(theMatch.Index + 1, theMatch.Length - 2)
            lines = lines.Insert(theMatch.Index + 1, lowerString)
        Next


        'fix easy tags
        lines = lines.Replace("<", "&#60")
        lines = lines.Replace(">", "&#62")
        lines = lines.Replace(ControlChars.Cr, "<br>")
        lines = lines.Replace("[b]", "<b>")
        lines = lines.Replace("[/b]", "</b>")
        lines = lines.Replace("[u]", "<u>")
        lines = lines.Replace("[/u]", "</u>")
        lines = lines.Replace("[i]", "<i>")
        lines = lines.Replace("[/i]", "</i>")
        lines = lines.Replace("[sup]", "<sup>")
        lines = lines.Replace("[/sup]", "</sup>")
        lines = lines.Replace("[sub]", "<sub>")
        lines = lines.Replace("[/sub]", "</sub>")
        lines = lines.Replace("[left]", "<div align=""left"">")
        lines = lines.Replace("[center]", "<div align=""center"">")
        lines = lines.Replace("[right]", "<div align=""right"">")
        lines = lines.Replace("[/left]", "</div>")
        lines = lines.Replace("[/center]", "</div>")
        lines = lines.Replace("[/right]", "</div>")
        lines = lines.Replace("[indent]", "<blockquote>")
        lines = lines.Replace("[/indent]", "</blockquote>")
        lines = lines.Replace("[s]", "<s>")
        lines = lines.Replace("[/s]", "</s>")
        lines = lines.Replace("[*]", "<li>")
        lines = lines.Replace("[hr]", "<hr />")
        lines = lines.Replace("<ul><br>", "<ul>")
        lines = lines.Replace("[code]", "<div class=codetop>CODE</div><div class=codemain>")
        lines = lines.Replace("[/code]", "</div>")

        'fix IMG's
        lines = Regex.Replace(lines, "(.*?)\[(?i)img\](.*?)\[/img\](.*?)", "$1" & "<img src='" & "$2" & "' border='0' alt='user posted image' />" & "$3")

        'Fix URL's
        lines = Regex.Replace(lines, "(?<!.*[""'])(ftp|http|https){1}:\/\/([^]> ]+)", "<a href=" & "$1" & "://" & "$2" & ">" & "$1" & "://" & "$2" & "</a>")
        lines = Regex.Replace(lines, "(.*?)\[(?i)url=<a href=(.+?)>+?(.*?)</a>]", "$1" & "<a href=" & "$2" & ">")
        lines = lines.Replace("[/url]", "</a>")



        'fix colors
        lines = Regex.Replace(lines, "(.*?)\[(?i)color=""(.*?)""\](.*?)", "$1" & "<span style=" & Chr(34) & "color:" & "$2" & Chr(34) & ">" & "$3")
        lines = Regex.Replace(lines, "(.*?)\[(?i)color=(.*?)\](.*?)", "$1" & "<span style=" & Chr(34) & "color:" & "$2" & Chr(34) & ">" & "$3")
        lines = lines.Replace("[/color]", "</span>")


        'fix advanced quote boxes
        lines = Regex.Replace(lines, "(.*?)\[(?i)quote=(.+?)\](.*?)", "$1" & "<div class=quotetop>QUOTE(" & "$2" & ")</div><div class=quotemain>" & "$3")

        'fix email
        lines = Regex.Replace(lines, "(.*?)\[(?i)email=(.+?)\](.*?)\[/email\](.*?)", "$1" & "<a href='mailto:" & "$2" & ">" & "$3" & "</a>" & "$4")

        'fix font
        lines = Regex.Replace(lines, "(.*?)\[(?i)font=(.+?)\](.*?)\[/font\](.*?)", "$1" & "<span style=" & Chr(34) & "FONT-FAMILY: " & "$2" & Chr(34) & ">" & "$3" & "</span>" & "$4")


        'fix lists

        val = InStr(lines, "[list]")
        If val = 0 Then
            val = InStr(lines, "[list=1]")
            If val = 0 Then
                val = InStr(lines, "[list=i]")
                If val = 0 Then
                    val = InStr(lines, "[list=a]")
                    If val = 0 Then
                        lines = lines
                    Else
                        lines = lines.Replace("[list=a]", "<ol type='a'>")
                        listTags = listTags & "a"
                    End If
                Else
                    lines = lines.Replace("[list=i]", "<ol type='i'>")
                    listTags = listTags & "i"
                End If
            Else
                lines = lines.Replace("[list=1]", "<ol type='1'>")
                listTags = listTags & "1"
            End If
        Else
            lines = lines.Replace("[list]", "<ul>")
            listTags = listTags & "0"
        End If

        If listTags.Length > 0 Then
            val = InStr(lines, "[/list]")
            If val <> 0 Then
                Dim closingtag As String
                closingtag = listTags.Substring(listTags.Length - 1)
                listTags = listTags.Remove(listTags.Length - 1)
                Select Case closingtag
                    Case "0"
                        lines = lines.Replace("[/list]", "</ul>")
                    Case "1"
                        lines = lines.Replace("[/list]", "</ol>")
                    Case "i"
                        lines = lines.Replace("[/list]", "</ol>")
                    Case "a"
                        lines = lines.Replace("[/list]", "</ol>")
                End Select
            End If
        End If

        'Fix other random junk (take a look here to see if everything's in place)
        lines = lines.Replace("[/font]", "</span>")
        lines = lines.Replace("[quote]", "<div class=quotetop>QUOTE</div><div class=quotemain>")
        lines = lines.Replace("<div class=quotemain><br>", "<div class=quotemain>")
        lines = lines.Replace("[/quote]", "</div><br>")
        lines = lines.Replace("[size=1]", "<span style=" & Chr(34) & "FONT-SIZE: 8pt; LINE-HEIGHT: 100%" & Chr(34) & ">")
        lines = lines.Replace("[size=2]", "<span style=" & Chr(34) & "FONT-SIZE: 10pt; LINE-HEIGHT: 100%" & Chr(34) & ">")
        lines = lines.Replace("[size=3]", "<span style=" & Chr(34) & "FONT-SIZE: 12pt; LINE-HEIGHT: 100%" & Chr(34) & ">")
        lines = lines.Replace("[size=4]", "<span style=" & Chr(34) & "FONT-SIZE: 14pt; LINE-HEIGHT: 100%" & Chr(34) & ">")
        lines = lines.Replace("[size=5]", "<span style=" & Chr(34) & "FONT-SIZE: 18pt; LINE-HEIGHT: 100%" & Chr(34) & ">")
        lines = lines.Replace("[size=6]", "<span style=" & Chr(34) & "FONT-SIZE: 24pt; LINE-HEIGHT: 100%" & Chr(34) & ">")
        lines.Replace("[size=7]", "<span style=" & Chr(34) & "FONT-SIZE: 36pt; LINE-HEIGHT: 100%" & Chr(34) & ">")
        lines = lines.Replace("[/size]", "</span>")

        Return (lines)

    End Function
End Class
